home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Other Stuff / Other Stuff ’97 / PowerOS Development / booter / booter.c < prev    next >
C/C++ Source or Header  |  1997-06-26  |  4KB  |  149 lines

  1. /*
  2.     boot.c
  3.     Application-Based Booter for PowerOS and OpenOS
  4.     copyright 1996-1997 by Ben Martz
  5.     all rights reserved world wide
  6.  
  7.     ANY AND ALL MODIFICATIONS TO THIS SOURCE MUST CREDIT THE ORIGINAL
  8.     AUTHOR, BEN MARTZ (benmartz@ic.net), AND MUST BE GIVEN TO THE AUTHOR
  9.     FOR INTEGRATION INTO THE MAIN PowerOS SOURCE TREE. THANK YOU FOR YOUR
  10.     COOPERATION!
  11. */
  12.  
  13. #include <stdio.h>
  14. #include "booter.h"
  15. #include "boot.h"
  16. #include "stdhdr.s"
  17. #include "garymode.h"
  18. #include <ShutDown.h>
  19.  
  20. KernelBootData        *kvars;
  21. DialogPtr            status;
  22. Ptr                    kernel;
  23. long                kernellen;
  24.  
  25. char *LogicalToPhysical(char *p, unsigned long plen);
  26. void bootkernel(char *from, unsigned long len, KernelBootData *vars);
  27. long elf_makeimage(char *fname, char **kptr);
  28.  
  29. void main(void) {
  30.     InitGraf(&qd.thePort);
  31.     InitFonts();
  32.     InitWindows();
  33.     InitMenus();
  34.     TEInit();
  35.     InitDialogs(0L);
  36.     InitCursor();
  37.     
  38.     status = GetNewDialog(128,nil,(WindowPtr) -1L); if(!status) return;
  39.     UpdateStatus("\pInitializing PowerOS Booter");
  40.     
  41.     /* these will be passed into the kernel */
  42.     kvars = (KernelBootData *) NewPtrSysClear(sizeof(KernelBootData));
  43.     kvars->version = BOOTVERSION;
  44.     kvars->v_baseaddr = LMGetScrnBase();
  45.     kvars->v_rowbytes = (**(**LMGetMainDevice()).gdPMap).rowBytes & 0x3fff;
  46.     kvars->v_depth = (**(**LMGetMainDevice()).gdPMap).pixelSize;
  47.     kvars->v_width = (**LMGetMainDevice()).gdRect.right - (**LMGetMainDevice()).gdRect.left;
  48.     kvars->v_height = (**LMGetMainDevice()).gdRect.bottom - (**LMGetMainDevice()).gdRect.top;
  49.     Gestalt(gestaltPhysicalRAMSize, &(kvars->m_bytes));
  50.     
  51.     UpdateStatus("\pLoading PowerOS Kernel");
  52.     
  53.     if((kernellen = elf_makeimage("kernel.elf",&kernel)) < 0) {
  54.         UpdateStatus("\pFailed to load ELF binary! Click to exit...");
  55.         while(!Button());
  56.         ExitToShell();
  57.     }
  58.     
  59.     /* we need to get the physical address of the kernel data */
  60.     LockMemory(kernel,kernellen);
  61.     
  62.     /* translate the address */
  63.     kernel = LogicalToPhysical(kernel,kernellen);
  64.     if(kernel == ((char *)0xdeadbeef)) {
  65.         UpdateStatus("\pLogicalToPhysical failed! Click to exit...");
  66.         while(!Button());
  67.         ExitToShell();
  68.     }
  69.     
  70.     /* this is a really good way to get a clean boot (from an application) */
  71.     UpdateStatus("\pShutting down MacOS");
  72.     ShutDwnInstall(NewShutDwnProc(boot), sdOnPowerOff);
  73.     ShutDwnPower();
  74.     
  75.     /* just wait for the system to shutdown so our code stays in memory */
  76.     while(1) {
  77.         HideCursor();
  78.         SystemTask();
  79.     }
  80. }
  81.  
  82. void UpdateStatus(unsigned char *string) {
  83.     short    itemType;
  84.     Handle    itemHandle;
  85.     Rect    itemRect;
  86.     
  87.     SetPort(status);
  88.     GetDialogItem(status,3,&itemType,&itemHandle,&itemRect);
  89.     DrawDialog(status);
  90.     EraseRect(&itemRect);
  91.     MoveTo(itemRect.left + (((itemRect.right - itemRect.left) / 2) - (StringWidth(string) / 2)),itemRect.bottom - 4);
  92.     DrawString(string);
  93. }
  94.  
  95. void boot(void) {
  96.     UpdateStatus("\pBooting PowerOS");
  97.     
  98.     EnterPriviledgedMode(bootkernel,(void *)kernel,(void *)kernellen,(void *)kvars);
  99.     
  100.     /* ouch? */
  101.     UpdateStatus("\pIf you see this, your system is possessed!");
  102. }
  103.  
  104. /* it appears that a 6100 running 7.6 is mapped 1:1 -- hmmm? */
  105. char *LogicalToPhysical(char *p, unsigned long plen) {
  106.     LogicalToPhysicalTable    table;
  107.     unsigned long            count;
  108.  
  109.     table.logical.address = p;
  110.     table.logical.count = plen;
  111.     count = sizeof(table) / sizeof(MemoryBlock) - 1;
  112.     if(GetPhysical(&table,&count) == noErr) {
  113.         return table.physical[0].address;
  114.     }
  115.     
  116.     return (char *)0xdeadbeef;
  117. }
  118.  
  119. asm void bootkernel(char *from, unsigned long len, KernelBootData *vars) {
  120.     /* turn off external interrupts during copy */
  121.     lis        r9,MSR_KERNEL
  122.     ori        r9,r9,MSR_KERNEL
  123.     mtmsr    r9
  124.     /*
  125.         unlike some sloppy code that i've seen, a synchronizing
  126.         operation is only necessary AFTER the mtmsr -- read your
  127.         damn reference manuals!!!
  128.     */
  129.     sync
  130.  
  131.     /* relocate the kernel to zero */
  132.     mtctr    r4
  133.     li        r6,0
  134.     subi    r3,r3,1
  135.     subi    r6,r6,1
  136. loop:
  137.     lbzu    r9,1(r3)
  138.     stbu    r9,1(r6)
  139.     bdnz+    loop
  140.  
  141.     /* put the boot vars where they belong */
  142.     mr        r3,r5
  143.     
  144.     /* jump to zero */
  145.     lis        r9,0
  146.     addi    r9,r9,0
  147.     mtlr    r9
  148.     blr
  149. }